package cn.kooki.app.duobao.ui.widget;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

import cn.kooki.app.duobao.R;
import cn.kooki.app.duobao.ui.view.CustomRefreshHeader;
import cn.kooki.app.duobao.ui.view.LoadMoreDefaultFooterView;
import cn.kooki.app.duobao.ui.view.LoadmoreFooter;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;

/**
 * Created by xiong on 2015/12/17.
 */
public class XRecylerView extends PtrFrameLayout {

    private Context context;
    private RecyclerView recyclerView;

    private boolean isnomore;
    private boolean isLoadingData;
    private boolean loadingMoreEnabled;


    private ArrayList<View> mHeaderViews = new ArrayList<>();
    private ArrayList<View> mFootViews = new ArrayList<>();
    private boolean pullRefreshEnabled = true;
    private CustomRefreshHeader customRefreshHeader;
    private int previousTotal = 0;
    private int mPageCount = 0;
    private Adapter mAdapter;
    private WrapAdapter mWrapAdapter;

    private static final int TYPE_HEADER = -4;
    private static final int TYPE_NORMAL = 0;
    private static final int TYPE_FOOTER = -3;
    private LoadingListener mLoadingListener;
    private LoadmoreFooter loadmoreFooter;

    /**
     * @param context
     */
    public XRecylerView(Context context) {
        this(context, null);
    }

    public XRecylerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public XRecylerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView();
    }

    public RecyclerView getRecyclerView() {
        return recyclerView;
    }

    private void initView() {
        context = getContext();
        recyclerView = new RecyclerView(context);
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        recyclerView.setLayoutParams(layoutParams);
        recyclerView.setVerticalScrollBarEnabled(true);
        recyclerView.setScrollBarStyle(SCROLLBARS_INSIDE_OVERLAY);
        addView(recyclerView);
        if (pullRefreshEnabled) {
            customRefreshHeader = new CustomRefreshHeader(context);
            disableWhenHorizontalMove(true);
            addPtrUIHandler(customRefreshHeader);
            setHeaderView(customRefreshHeader);
            setPtrHandler(new PtrHandler() {
                @Override
                public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                    return PtrDefaultHandler.checkContentCanBePulledDown(frame, recyclerView, header);
                }

                @Override
                public void onRefreshBegin(PtrFrameLayout frame) {
                    if (mLoadingListener != null) {
                        mLoadingListener.onRefresh();
                        restMoreLoading();
                    }
                }
            });
        }


        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE && mLoadingListener != null && !isLoadingData && loadingMoreEnabled) {
                    RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                    int lastVisibleItemPosition;
                    if (layoutManager instanceof GridLayoutManager) {
                        lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
                    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                        int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
                        ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
                        lastVisibleItemPosition = findMax(into);
                    } else {
                        lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
                    }
                    if (layoutManager.getChildCount() > 0
                            && lastVisibleItemPosition >= layoutManager.getItemCount() - 1 &&
                            layoutManager.getItemCount() > layoutManager.getChildCount() &&
                            !isnomore && !isRefreshing()) {

                        View footView = mFootViews.get(0);
                        isLoadingData = true;
                        if (footView instanceof LoadmoreFooter) {
                            ((LoadmoreFooter) footView).setType(LoadmoreFooter.isLoadingData);
                        } else {
                            footView.setVisibility(View.VISIBLE);
                        }
                        mLoadingListener.onLoadMore();

                    }
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

            }
        });

        loadmoreFooter = new LoadmoreFooter(context);
        loadmoreFooter.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        loadmoreFooter.setType(LoadmoreFooter.ISNOTENABLE);
        addFootView(loadmoreFooter);
    }


    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }

    public void setPullRefreshEnabled(boolean pullRefreshEnabled) {
        this.pullRefreshEnabled = pullRefreshEnabled;
        if (!pullRefreshEnabled) {
            setHeaderView(null);
        } else {
            setHeaderView(customRefreshHeader);
        }
    }


    public void noMoreLoading() {
        isLoadingData = false;
        View footView = mFootViews.get(0);
        isnomore = true;
        if (footView instanceof LoadmoreFooter) {
            ((LoadmoreFooter) footView).setType(LoadmoreFooter.ISEND);
        } else {
            footView.setVisibility(View.GONE);
        }
    }

    public void restMoreLoading() {
        isLoadingData = false;
        View footView = mFootViews.get(0);
        isnomore = false;
        if (footView instanceof LoadmoreFooter) {
            ((LoadmoreFooter) footView).setType(LoadmoreFooter.NORMAL);
        } else {
            footView.setVisibility(View.GONE);
        }
    }

    public void setAdapter(Adapter adapter) {
        mAdapter = adapter;
        mWrapAdapter = new WrapAdapter(mHeaderViews, mFootViews, adapter);
        recyclerView.setAdapter(mWrapAdapter);

        mAdapter.registerAdapterDataObserver(mDataObserver);
    }

    public void setLoadingMoreEnabled(boolean enabled) {
        loadingMoreEnabled = enabled;
        if (!enabled) {
            if (mFootViews.size() > 0) {
                mFootViews.get(0).setVisibility(GONE);
                mFootViews.remove(loadmoreFooter);
            }
        }
    }

    public void setLayoutManager(LayoutManager layout) {
        if (layout != null) {
            recyclerView.setLayoutManager(layout);
        }
    }


    public void loadMoreComplete() {
        isLoadingData = false;
        View footView = mFootViews.get(0);
        if (footView instanceof LoadmoreFooter) {
            ((LoadmoreFooter) footView).setType(LoadmoreFooter.LOADING_COMPELETE);
        } else {
            footView.setVisibility(View.GONE);
        }

    }

    public void addHeaderView(View view) {

        mHeaderViews.add(view);
    }

    public void addFootView(View view) {
        mFootViews.clear();
        mFootViews.add(view);
    }


    public void setLoadingListener(LoadingListener listener) {
        mLoadingListener = listener;
    }

    private final RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            mWrapAdapter.notifyDataSetChanged();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount);
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount);
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount);
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            mWrapAdapter.notifyItemMoved(fromPosition, toPosition);
        }
    };

    class WrapAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private int headerPosition = 0;

        private RecyclerView.Adapter adapter;

        private ArrayList<View> mHeaderViews;

        private ArrayList<View> mFootViews;


        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
            if (manager instanceof GridLayoutManager) {
                final GridLayoutManager gridManager = ((GridLayoutManager) manager);
                gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        return (isHeader(position) || isFooter(position))
                                ? gridManager.getSpanCount() : 1;
                    }
                });
            }
        }


        public boolean isHeader(int position) {
            return position >= 0 && position < mHeaderViews.size();
        }

        public boolean isFooter(int position) {
            return position < getItemCount() && position >= getItemCount() - mFootViews.size();
        }

        public int getHeadersCount() {
            return mHeaderViews.size();
        }

        public int getFootersCount() {
            return mFootViews.size();
        }

        public WrapAdapter(ArrayList<View> mHeaderViews, ArrayList<View> mFootViews, Adapter adapter) {
            this.mHeaderViews = mHeaderViews;
            this.mFootViews = mFootViews;
            this.adapter = adapter;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == TYPE_HEADER) {

                return new SimpleViewHolder(mHeaderViews.get(headerPosition++));
            } else if (viewType == TYPE_FOOTER) {
                return new SimpleViewHolder(mFootViews.get(0));
            }
            return adapter.onCreateViewHolder(parent, viewType);
        }


        @Override
        public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
            super.onViewAttachedToWindow(holder);
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
            if (lp != null
                    && lp instanceof StaggeredGridLayoutManager.LayoutParams
                    && (isHeader(holder.getLayoutPosition()) || isFooter(holder.getLayoutPosition()))) {
                StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
                p.setFullSpan(true);
            }
        }

        @Override
        public int getItemViewType(int position) {

            if (isHeader(position)) {
                return TYPE_HEADER;
            }
            if (isFooter(position)) {
                return TYPE_FOOTER;
            }
            int adjPosition = position - getHeadersCount();
            ;
            int adapterCount;
            if (adapter != null) {
                adapterCount = adapter.getItemCount();
                if (adjPosition < adapterCount) {
                    return adapter.getItemViewType(adjPosition);
                }
            }
            return TYPE_NORMAL;
        }


        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            if (isHeader(position)) {
                return;
            }
            int adjPosition = position - getHeadersCount();
            int adapterCount;
            if (adapter != null) {
                adapterCount = adapter.getItemCount();
                if (adjPosition < adapterCount) {
                    adapter.onBindViewHolder(holder, adjPosition);
                    return;
                }
            }
        }

        @Override
        public int getItemCount() {
            if (adapter != null) {
                return getHeadersCount() + getFootersCount() + adapter.getItemCount();
            } else {
                return getHeadersCount() + getFootersCount();
            }
        }

        private class SimpleViewHolder extends RecyclerView.ViewHolder {
            public SimpleViewHolder(View itemView) {
                super(itemView);
            }
        }
    }

    public interface LoadingListener {

        void onRefresh();

        void onLoadMore();
    }

}
